/**
 * 
 */
package com.hp.bon.sgw.core.channel.handler;

import java.io.IOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hp.bon.security.Constants.DiameterAVP;
import com.hp.bon.sgw.Constants;
import com.hp.bon.sgw.Constants.CRMCBResult;
import com.hp.bon.sgw.bean.XmlMessage;
import com.hp.bon.sgw.core.CallParam;
import com.hp.bon.sgw.core.channel.NAVSoapChannel;
import com.hp.bon.sgw.threads.TaskManager;
import com.hp.ocs.diameter.message.AVP;
import com.hp.ocs.diameter.message.AVP_Grouped;
import com.hp.ocs.diameter.message.AVP_UTF8String;
import com.hp.ocs.diameter.message.AVP_Unsigned32;
import com.hp.ocs.diameter.message.InvalidAVPLengthException;
import com.hp.ocs.diameter.message.Message;

/**
 * @author sunhaiy
 * 
 */
public class NAVCallHandler implements IAsynCallHandler {
	private static final Logger logger = LoggerFactory.getLogger(NAVCallHandler.class);
	PrintStream printStream;

	public NAVCallHandler(PrintStream printStream) {
		this.printStream = printStream;
	}

	@Override
	public void onCallResult(CallParam callParam) {

		XmlMessage ack = new XmlMessage(false);
		// SgwAck ack = new SgwAck();

		ack.setMID(callParam.getSessionId());

		Object response = null;

		if (callParam.getResponse() != null) {
			response = callParam.getResponse();
		} else if (callParam.getRecvResponse() != null) {
			response = callParam.getRecvResponse();
		}

		if (response == null) {
			ack.setRC((callParam.getRetCode() == 3002 ? CRMCBResult.WS_RCVER_SGW_NOT_AVAIBLE : callParam.getRetCode()) + "");
			ack.setDS(callParam.getResultMsg());
		} else {
			if (response instanceof Message) {
				Message resp = (Message) response;
				AVP resultCodeAVP = resp.find(Constants.DIAMETER_AVP_RESULT_CODE);

				if (resultCodeAVP == null) {
					ack.setRC(CRMCBResult.WS_RCVER_BON_BIZ_ERROR + "");
					ack.setDS("CCA missing Result-Code AVP");
				} else {
					try {
						int rcode = new AVP_Unsigned32(resultCodeAVP).queryValue();
						if (rcode != Constants.DIAMETER_RESULT_SUCCESS) {
							ack.setRC(CRMCBResult.WS_RCVER_BON_NE_ERR + "");
							ack.setDS("Result-Code is " + rcode);
						} else {
							AVP avp = resp.find(DiameterAVP.SERVICE_INFOMATION, Constants.DIAMETER_VENDOR_3GPP);
							if (null != avp) {
								AVP_Grouped serviceInfoAVP = new AVP_Grouped(avp);
								AVP serviceResultCodeAVP = serviceInfoAVP.find(Constants.DIAMETER_AVP_SERVICE_RESULT_CODE, Constants.DIAMETER_VENDOR_CT);
								if (serviceResultCodeAVP == null) {
									ack.setRC(CRMCBResult.WS_RCVER_BON_BIZ_ERROR + "");
									ack.setDS("CCA missing Service-Result-Code AVP");
								} else {
									int rc = new AVP_Unsigned32(serviceResultCodeAVP).queryValue();
									ack.setRC(rc + "");
									AVP failedAvp = serviceInfoAVP.find(Constants.DIAMETER_AVP_Para_Field_Result, Constants.DIAMETER_VENDOR_CT);
									if (failedAvp != null) {
										String failed = new AVP_UTF8String(failedAvp).queryValue();
										ack.setDS(failed);
									}
								}
							} else {
								ack.setRC(CRMCBResult.WS_RCVER_BON_BIZ_ERROR + "");
								ack.setDS("CCA missing Service-Information AVP");
							}
						}
					} catch (InvalidAVPLengthException e1) {
						ack.setRC(CRMCBResult.WS_RCVER_BON_NE_ERR + "");
						ack.setDS("InvalidAVPLengthException");
						e1.printStackTrace();
					}
				}
			} else if (response instanceof XmlMessage) {
				ack = (XmlMessage) response;
			} else {
				logger.warn("unknown response type:" + callParam.getResponse().getClass().getName());
			}
		}

		try {
			NAVSoapChannel.responseACK(printStream, ack);

			if (ack.getDS() != null) {
				callParam.setResultMsg(ack.getDS());
			}
			callParam.setResponse(ack);
			TaskManager.taskProcess(callParam);

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	@Override
	public int getProtocolType() {
		// TODO Auto-generated method stub
		return 0;
	}

}